/**
 * $File: TT_Core.h
 * $Synopsis: Core Stuff Header
 * $Author: Ted Yin (ymfoi)
 * $Version: alpha 1.0
 * $Date: Thu Nov 25 20:55:50 2010 CST
 */

#ifndef TT_CORE_H
#define TT_CORE_H

#include <cstdlib>
#include <cstring>

	
typedef unsigned char UCHAR;

namespace TT_Core {

	struct Pos {

		int x,y;
	};

	struct PosNode : public Pos {

		PosNode *next;
		PosNode();
	};

	struct PosList {

		PosNode *head;

		void Add(int x,int y);

		PosList();
		~PosList();
	};

	struct PlayerNode : public Pos {

		PosList Route;
		int Now_Dir,ID;
		unsigned char Red,Green,Blue;
		bool IsDead;	
		double ds,Speed,Alpha;

		PlayerNode *next,*prev;

		PlayerNode();
	};


#define MAXID 1003
#define SPEED_PRECISION 100
#define MAX_SPEED 0.5

#define ACT_TYPE_LEFT 0
#define ACT_TYPE_RIGHT 1
#define ACT_TYPE_SPEEDUP 2
#define ACT_TYPE_SPEEDDOWN 3

#define ERR_NUM_PLAYER_NOT_FOUND 1
#define ERR_NUM_PLAYER_NOT_ALIVE 2
#define ERR_NUM_POS_OCCUPIED 3
#define ERR_NUM_POS_INVALID 4
#define ERR_NUM_DIR_INVALID 5
#define ERR_NUM_ACT_INVALID 6


	struct PlayerList {

		PlayerNode *head;
		PlayerNode *Hash[MAXID];
		int Recycle[MAXID],*Top,ID_Cnt;

		PlayerList();
		~PlayerList();

		int Add(int x,int y,int Dir,int InitSpeed);
		void Del(int ID);

		PlayerNode *GetInfo(int ID);

	};


	class Arena {

		int **Map;
		// 0 -- unoccupied
		// x -- occupied by x
		//
		int Height,Width;
		PlayerList *Players;
		PlayerNode *Dead[MAXID],**Dead_Ptr;

		public:

		PlayerNode **Dead_Head,*Player_Head;

		int Err_Num; //Error Code if it's not zero.
		int Player_Num; //The Number of Current Player


		explicit Arena(int Height,int Width); //the Constructor

		void InitMatch(); //Call this before the Round begins

		int AddPlayer(int x,int y,int Dir,int InitSpeed,UCHAR R,UCHAR G,UCHAR B); //Add a Player and return the new player's ID

		bool DelPlayer(int ID); //Delete a Player 

		void IdleMove(); //All players move in their current directions in Delta Time

		static void IdleMoveReal(Arena *Real); //Staic func

		bool FlushPlayer(int ID,int ActType); //Let the player Do a Certain Action Immediately

		const int **GetMap(); //view the whole map;

		const PlayerNode *GetPlayer(int ID);

		const PlayerNode *GetPlayerIterator(); //Get Iterator
	};

#define OBJ_STATE_RUNNING 1
#define OBJ_STATE_SLEEPING 2
#define OBJ_STATE_EXIT 0

	struct ObjectNode {

		ObjectNode *next,*prev;
		void (*ptr)(void *);
		void *Real;
		int State,ID;

		ObjectNode();
	};

#define ERR_NUM_OBJ_NOT_FOUND 1


	class AnimaStage {

		ObjectNode *head;
		ObjectNode *Hash[MAXID];
		int Recycle[MAXID],*Top,ID_Cnt;

		void DelObject(ObjectNode *ptr);
		
		public:

		int Err_Num;

		AnimaStage();
		~AnimaStage();

		int AddObject(void (*func)(void *Real),void *Real);

		bool SendSignal(int Sig,int ID);

		void MoveOn(double DetTime);
	};

}

#endif //TT_CORE_H
